`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/09/26 15:37:31
// Design Name: 
// Module Name: signed_multiplier
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module signed_multiplier(
    input mul_clk,
    input resetn,
    input mul_signed,
    input [31:0] x,
    input [31:0] y,
    output [63:0] result
    );
	wire [63:0]in1_se;
    wire [63:0]p[16:0];
    reg  [16:0]p1[63:0];
    wire [63:0]S,C;
    wire [16:0]c;
    reg  [16:0]c_r;
    wire [13:0]cout[63:0];
    wire [33:0]y1;
    wire cout_64;
    assign in1_se=(mul_signed)?{{32{x[31]}},x}:{32'b0,x};
    assign y1=(mul_signed)?{{2{y[31]}},y}:{2'b0,y};
    //boothģ��
    genvar i,j;

    generate 
        for(i=0;i<=16;i=i+1) begin:bp
            booth_partial u_booth_partial(in1_se,(2*i-1>0)?y1[2*i-1]:1'b0,y1[2*i],y1[2*i+1],(2*i),p[i],c[i]);
        end
    endgenerate
    
    generate
        
            for(i=0;i<=63;i=i+1) begin
                for(j=0;j<=16;j=j+1) begin
                    always @(posedge mul_clk) begin
                        if(!resetn) begin
                            p1[i][j] <= 1'b0;
                        end
                        else begin
                            p1[i][j] <= p[j][i];
                        end
                    end
                end
            end
        
    endgenerate
    always @(posedge mul_clk) begin
            if(!resetn) begin
                c_r <= 17'b0;
            end
            else begin
                c_r <= c;
            end
    end
    //����ʿ��ģ��
    generate 
        for(i=0;i<=63;i=i+1) begin:wt
            Wallace_tree_16 u_Wallace_tree_16(p1[i],(i==0)?c_r[13:0]:cout[i-1],S[i],C[i],cout[i]);
        end
    endgenerate
    //64λ��ǰ��λ�ӷ���ģ��
    adder_64_head ah(S,{C[62:0],c_r[15]},c_r[14],result,cout_64);
    endmodule
